//这里的代码必须亲力亲为  自己写
// 路由守卫代码
import router, { asyncRoutes } from "./router";

// 导入store
import store from "@/store";

// 导入nprogress模块（进入页面的加载提示）
import NProgress from "nprogress";
// 导入nprogress样式
import "nprogress/nprogress.css";

//比白名单数组 这里放的是不用等登入就可以访问的路由路径
const whiteList = ["/login", "/404"];

// 注册全局守卫前置
router.beforeEach(async (to, from, next) => {
  // 开启进度条加载提示
  NProgress.start();
  // 获取token
  const { token } = store.state.user;
  //判断
  if (token) {
    //登入了
    //如果要去的路由在白名单
    if (to.path === "/login") {
      // 没必要去了  去首页
      next("/");
      NProgress.done();
    } else {
      // 获取用户信息的action在这里调用
      // 注意：
      //1.此项目的核心在权限控制  就是不同员工登入的主页菜单不同
      //2. 如果员工登入成功了 已经跳转了主页才发请求  获取员工的角色权限已经太晚了
      // 3.这个获取员工权限的信息是在跳转到主页之前  拿到当前员工的角色信息
      // 知道你是谁了  知道有那些权限然后再对应开放左侧菜单  这些都做完了
      //  再让员工跳转 这个时候他看到的左侧菜单就是他所具备的权限
      // 4.只是现在还不知道如何开放对应的左侧菜单

      //这个地方代码当路由器切换的时候会多次执行  多次发起请求 需要优化
      //第一种解决方式：判断vuex中的userID有没有
      if (!store.state.user.userInfo.userId) {
        // 这里拿到了用户的信息   用户信息里面有这个  userInfo.roles.menus 可以拿到当前员工列表
        //这个角色列表数组中的字符串表明了当前员工可以看到的左侧菜单   以后基于这个数组对动态路由表做筛选
        // 然后调至首页  这样首页展示的左侧菜单就是当前员工能看到的
        await store.dispatch("user/getUserInfoAction");
        //获取当前用户的menus数组
        const { menus } = store.state.user.userInfo.roles;
        //  基于当前用户信息中roles.menus数组来筛选动态数组
        // 筛选的条件：判断当前路由的第一个children的明智是否在menus数组中
        // 在的话就留下开放   否则过滤掉
        // 触发route / filterAsyncRouteAction;函数 拿到筛选后的动态路由
        const showAsyncRoutes = await store.dispatch(
          "route/filterAsyncRouteAction",
          menus
        );

        // 实例必须通过await拿到
        // 把筛选的结果动态追加到路由表中
        router.addRoutes([
          ...showAsyncRoutes,
          {
            path: "*",
            redirect: "/404",
            hidden: true,
          },
        ]);
        //刷新一下路由表
        return next({
          ...to, //保留原有的所有要去的路由的信息
          replace: true, //替换刚刚跳转的历史记录
        });
        // console.log(6666666);
      }
      // 第二种解决方式
      // 所有的action函数返回的都是Promise实例  要接受必须配合await
      // const userObj = await store.dispatch('user/getUserInfoAction')

      //否则放行
      next();
    }
  } else {
    //未登入
    //进一步判断，要去的路由是否在白名单
    if (whiteList.includes(to.path)) {
      // 如果在
      //   放行
      next();
    } else {
      // 否则
      // 跳转至登入  并携带回调地址
      next(`/login?redirectUrl=${to.path}`);
      NProgress.done();
    }
  }
});
//注册全局后置守卫
router.afterEach(() => {
  NProgress.done();
});
